﻿#region Copyright & License

// Copyright © 2012 - 2013 François Chabot, Yves Dierick
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#endregion

using System;
using System.Linq;
using Be.Stateless.BizTalk.Monitoring.Model;
using Be.Stateless.BizTalk.Schema;
using Be.Stateless.BizTalk.Schemas.Xml;
using Be.Stateless.BizTalk.Tracking;
using Be.Stateless.BizTalk.Unit.Process;
using Microsoft.BizTalk.Operations;
using NUnit.Framework;

namespace Be.Stateless.BizTalk.Processes.Batch
{
	[TestFixture]
	public class AggregateProcessFixture : ProcessFixture
	{
		#region Setup/Teardown

		[SetUp]
		public void Setup()
		{
			BatchAdapter.RegisterBatch(_envelopeSpecName, null, true, 3);
			DropFolders.ClearInputFolders();
		}

		[TearDown]
		public void TearDown()
		{
			BatchAdapter.ClearParts();
			BatchAdapter.UnregisterBatch(_envelopeSpecName, null);
			DropFolders.ClearOutputFolders();
			TerminateUncompletedBizTalkServiceInstances();
		}

		#endregion

		[Test]
		public void AddPartToBatch()
		{
			BatchAdapter.CreatePartMessage(_envelopeSpecName, null).SaveToInputFolder("part.xml.part");

			var process = TrackingRepository.SingleProcess(
				p => p.Name == Factory.Processes.Batch.Aggregate
					&& p.BeginTime > StartTime);
			process.SingleMessagingStep(
				s => s.Name == "BizTalk.Factory.RL1.UnitTest.Batch.AddPart.FILE.XML"
					&& s.MessageType == new SchemaMetadata<Any>().MessageType
					&& s.Status == TrackingStatus.Received
					&& _envelopeSpecName.StartsWith(s.Value1, StringComparison.Ordinal)
					&& s.Value2 == null);
			var addPartMessage = process.SingleMessagingStep(
				s => s.Name == "BizTalk.Factory.SP1.Batch.AddPart.WCF-SQL.XML"
					&& s.MessageType == new SchemaMetadata<Any>().MessageType
					&& s.Status == TrackingStatus.Sent
					&& _envelopeSpecName.StartsWith(s.Value1, StringComparison.Ordinal)
					&& s.Value2 == null);

			var part = BatchAdapter.Parts.Single();
			Assert.That(part.MessagingStepActivityId, Is.EqualTo(addPartMessage.ActivityID));
			Assert.That(part.Partition, Is.EqualTo("0"));

			Assert.That(UncompletedBizTalkServiceInstances, Is.EquivalentTo(Enumerable.Empty<MessageBoxServiceInstance>()));
		}

		[Test]
		public void AddPartToPartionnedBatch()
		{
			BatchAdapter.CreatePartMessage(_envelopeSpecName, "partition-z").SaveToInputFolder("part.xml.part");

			var process = TrackingRepository.SingleProcess(
				p => p.Name == Factory.Processes.Batch.Aggregate
					&& p.BeginTime > StartTime);
			process.SingleMessagingStep(
				s => s.Name == "BizTalk.Factory.RL1.UnitTest.Batch.AddPart.FILE.XML"
					&& s.MessageType == new SchemaMetadata<Any>().MessageType
					&& s.Status == TrackingStatus.Received
					&& _envelopeSpecName.StartsWith(s.Value1, StringComparison.Ordinal)
					&& s.Value2 == "partition-z");
			var addPartMessage = process.SingleMessagingStep(
				s => s.Name == "BizTalk.Factory.SP1.Batch.AddPart.WCF-SQL.XML"
					&& s.MessageType == new SchemaMetadata<Any>().MessageType
					&& s.Status == TrackingStatus.Sent
					&& _envelopeSpecName.StartsWith(s.Value1, StringComparison.Ordinal)
					&& s.Value2 == "partition-z");

			var part = BatchAdapter.Parts.Single();
			Assert.That(part.MessagingStepActivityId, Is.EqualTo(addPartMessage.ActivityID));
			Assert.That(part.Partition, Is.EqualTo("partition-z"));

			Assert.That(UncompletedBizTalkServiceInstances, Is.EquivalentTo(Enumerable.Empty<MessageBoxServiceInstance>()));
		}

		private static readonly string _envelopeSpecName = new SchemaMetadata<Envelope>().DocumentSpec.DocSpecStrongName;
	}
}
